#include "systemc.h"
#include "car.h"
#include "gas_station.h"
#include "Process.hpp"
#include "Stage.hpp"
#include "Concurrency.hpp"
#include "Event.h"
#include "Combined.h"
#include "Sensitivity.h"
#include "Initialization.h"
#include "EventQue.h"
#include "Method.h"
#include "Mutex.h"
#include "Semaphore.h"

using namespace sc_core;

void car_demo(){
    car car("car");
    sc_start(65, SC_SEC);
}


void gas_demo(){
    gas_station gas_station("gas_station");
    sc_start(100, SC_SEC);
}

void Process_demo(){
    Process process("process");
    cout << "execution phase begins @ " << sc_time_stamp() << endl;
    sc_start(2, sc_core::SC_SEC);
    cout << "execution phase ends @ " << sc_time_stamp() << endl;
}

void Stage_demo(){
    Stage stage("stage");
    cout << "execution phase begins @ " << sc_time_stamp() << endl;
    sc_start(5, sc_core::SC_SEC);
    cout << "execution phase ends @ " << sc_time_stamp() << endl;
}

void Concurrency_demo(){
    Concurrency concurrency("concurrency");
    sc_start(10, sc_core::SC_SEC);
}

void Event_demo(){
    Event evt("evt");
    sc_start(8, SC_SEC);
}

void Combined_demo(){
    Combined cmb("cmb");
    sc_start();
}

void Sensitive_damo(){
    Sensitivity sen("sen");
    sc_start(7, SC_SEC);
}

void Initialization_demo(){
    Initialization init("init");
    sc_start(4, SC_SEC);
}

void Method_demo(){
    Method mm("method");
    sc_start(5, SC_SEC);
}
void EventQue_demo(){
    EventQue eq("eq");
    sc_start(20, SC_SEC);
}

void Mutex_demo(){
    Mutex mtx("mtx");
    sc_start(10, SC_SEC);
}

void Semaphore_demo(){
    Semaphore sem("sem",2);
    sc_start(4, SC_SEC);
}



int time_demo(){
    sc_core::sc_report_handler::set_actions( "/IEEE_Std_1666/deprecated",sc_core::SC_DO_NOTHING );
    sc_set_time_resolution(1, SC_FS);
    sc_set_default_time_unit(1, SC_SEC);
    std::cout << "1 SEC =     " << sc_time(1, SC_SEC).to_default_time_units() << " SEC"<< std::endl;
    std::cout << "1  MS = " << sc_time(1, SC_MS).to_default_time_units()  << " SEC"<< std::endl;
    std::cout << "1  US = " << sc_time(1, SC_US).to_default_time_units()  << " SEC"<< std::endl;
    std::cout << "1  NS = " << sc_time(1, SC_NS).to_default_time_units()  << " SEC"<< std::endl;
    std::cout << "1  PS = " << sc_time(1, SC_PS).to_default_time_units()  << " SEC"<< std::endl;
    std::cout << "1  FS = " << sc_time(1, SC_FS).to_default_time_units()  << " SEC"<< std::endl;
    sc_start(7261, SC_SEC);
    double t = sc_time_stamp().to_seconds();
    std::cout << int(t) / 3600 << " hours, " << (int(t) % 3600) / 60 << " minutes, " << (int(t) % 60) << "seconds" << std::endl;
    return 0;
}


int sc_main(int argc, char *argv[])
{
//    car_demo();
//    gas_demo();
//    Process_demo();
//      Stage_demo();
//    time_demo();
//    Concurrency_demo();
//    Event_demo();
//    Combined_demo();
//    Sensitive_damo();
//    Initiailzation_demo();
//    Method_demo();
//    EventQue_demo();

//    Mutex_demo();
    Semaphore_demo();

    return 0;

}